package com.maodou.core.ui.components

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.navigationBars

/**
 * 通用弹框 UI 组件集合：居中弹出、底部弹出、顶部弹出
 *
 * 设计目标：
 * - 仅负责布局与动效，不直接创建 Dialog。可直接作为 GlobalUi.showDialog 的自定义内容使用
 * - 支持任意内容插槽，方便传入自定义 UI
 * - 支持点击遮罩关闭与返回键关闭
 */

// =============== 公共工具 ===============
@Composable
private fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier =
    this.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null,
        onClick = onClick
    )

// =============== 居中弹出 ===============
@Composable
fun CenterPopup(
    visible: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    scrimColor: Color = Color.Black.copy(alpha = 0.45f),
    dismissOnClickOutside: Boolean = true,
    enter: EnterTransition = fadeIn(animationSpec = tween(180)) + scaleIn(initialScale = 0.95f, animationSpec = tween(180)),
    exit: ExitTransition = fadeOut(animationSpec = tween(150)) + scaleOut(targetScale = 0.95f, animationSpec = tween(150)),
    containerColor: Color = MaterialTheme.colorScheme.surface,
    contentPadding: PaddingValues = PaddingValues(20.dp),
    shape: RoundedCornerShape = RoundedCornerShape(16.dp),
    elevation: Dp = 8.dp,
    dismissOnBackPress: Boolean = true,
    content: @Composable BoxScope.() -> Unit,
) {
    if (!visible) return

    BackHandler(enabled = visible) {
        if (dismissOnBackPress) onDismissRequest()
    }

    val transitionState = remember { MutableTransitionState(false) }.apply { targetState = visible }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(scrimColor)
            .semantics { testTag = "CenterPopup_Scrim" }
            .let { base ->
                if (dismissOnClickOutside) base.noRippleClickable(onDismissRequest) else base
            },
        contentAlignment = Alignment.Center
    ) {
        AnimatedVisibility(
            visibleState = transitionState,
            enter = enter,
            exit = exit
        ) {
            Surface(
                modifier = modifier,
                shape = shape,
                color = containerColor,
                tonalElevation = elevation,
                shadowElevation = elevation
            ) {
                Box(modifier = Modifier.padding(contentPadding)) {
                    content()
                }
            }
        }
    }
}

// =============== 底部弹出 ===============
@Composable
fun BottomPopup(
    visible: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    scrimColor: Color = Color.Black.copy(alpha = 0.45f),
    dismissOnClickOutside: Boolean = true,
    enter: EnterTransition = slideInVertically(initialOffsetY = { it }, animationSpec = tween(220)) + fadeIn(animationSpec = tween(180)),
    exit: ExitTransition = slideOutVertically(targetOffsetY = { it }, animationSpec = tween(200)) + fadeOut(animationSpec = tween(150)),
    containerColor: Color = Color.White,
    shape: RoundedCornerShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
    elevation: Dp = 8.dp,
    dismissOnBackPress: Boolean = true,
    content: @Composable ColumnScope.() -> Unit,
) {
    if (!visible) return

    BackHandler(enabled = visible) {
        if (dismissOnBackPress) onDismissRequest()
    }

    val transitionState = remember { MutableTransitionState(false) }.apply { targetState = visible }
    val navigationBarHeight = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(scrimColor)
            .semantics { testTag = "BottomPopup_Scrim" }
            .let { base ->
                if (dismissOnClickOutside) base.noRippleClickable(onDismissRequest) else base
            }
    ) {
        AnimatedVisibility(
            modifier = Modifier.align(Alignment.BottomCenter),
            visibleState = transitionState,
            enter = enter,
            exit = exit
        ) {
            Surface(
                modifier = modifier
                    .fillMaxWidth()
                    .imePadding(),
                shape = shape,
                color = containerColor,
                tonalElevation = elevation,
                shadowElevation = elevation
            ) {
                Column(
                    modifier = Modifier
                        .padding(bottom = navigationBarHeight),
                ) {
//                    DragHandle()
                    content()
                }
            }
        }
    }
}

// =============== 顶部弹出 ===============
@Composable
fun TopPopup(
    visible: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    scrimColor: Color = Color.Black.copy(alpha = 0.45f),
    dismissOnClickOutside: Boolean = true,
    enter: EnterTransition = slideInVertically(initialOffsetY = { -it }, animationSpec = tween(220)) + fadeIn(animationSpec = tween(180)),
    exit: ExitTransition = slideOutVertically(targetOffsetY = { -it }, animationSpec = tween(200)) + fadeOut(animationSpec = tween(150)),
    containerColor: Color = MaterialTheme.colorScheme.surface,
    shape: RoundedCornerShape = RoundedCornerShape(bottomStart = 16.dp, bottomEnd = 16.dp),
    elevation: Dp = 8.dp,
    dismissOnBackPress: Boolean = true,
    content: @Composable ColumnScope.() -> Unit,
) {
    if (!visible) return

    BackHandler(enabled = visible) {
        if (dismissOnBackPress) onDismissRequest()
        // else: consume back press to prevent page pop
    }

    val transitionState = remember { MutableTransitionState(false) }.apply { targetState = visible }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(scrimColor)
            .semantics { testTag = "TopPopup_Scrim" }
            .let { base ->
                if (dismissOnClickOutside) base.noRippleClickable(onDismissRequest) else base
            }
    ) {
        AnimatedVisibility(
            modifier = Modifier.align(Alignment.TopCenter),
            visibleState = transitionState,
            enter = enter,
            exit = exit
        ) {
            Surface(
                modifier = modifier
                    .fillMaxWidth(),
                shape = shape,
                color = containerColor,
                tonalElevation = elevation,
                shadowElevation = elevation
            ) {
                Column(
                    modifier = Modifier
                        .padding(horizontal = 16.dp, vertical = 12.dp),
                ) {
                    content()
                }
            }
        }
    }
}

@Composable
private fun ColumnScope.DragHandle(color: Color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.2f)) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(top = 8.dp, bottom = 12.dp),
        contentAlignment = Alignment.Center
    ) {
        Box(
            modifier = Modifier
                .background(color = color, shape = RoundedCornerShape(2.dp))
                .padding(vertical = 2.dp, horizontal = 18.dp)
        )
    }
}

// =============== 轻量示例预览（可选） ===============
@Preview(backgroundColor = 0xffffffff)
@Composable
private fun CenterPopupPreview() {
    MaterialTheme {
        CenterPopup(visible = true, onDismissRequest = {}) {
            Text(text = "居中弹框内容", style = MaterialTheme.typography.titleMedium)
        }
    }
}

@Preview(backgroundColor = 0xffffffff)
@Composable
private fun BottomPopupPreview() {
    MaterialTheme {
        BottomPopup(visible = true, onDismissRequest = {}) {
            Text(text = "底部弹框内容", style = MaterialTheme.typography.titleMedium)
        }
    }
}

@Preview(backgroundColor = 0xffffffff)
@Composable
private fun TopPopupPreview() {
    MaterialTheme {
        TopPopup(visible = true, onDismissRequest = {}) {
            Text(text = "顶部弹框内容", style = MaterialTheme.typography.titleMedium)
        }
    }
}
